﻿using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEditor.U2D;
using UnityEngine;
using UnityEngine.U2D;

/// <summary>
/// 游戏创建 Sprite Atlas 默认设置
/// </summary>
public static class GameCreateSpriteAtlasSetting
{

    class AtlasInfo
    {
        public string AtlasName { get; set; }
        public string AtlasPath { get; set; }
        public List<string> TexturePaths { get; set; } = new List<string>();
        public Object Obj { get; set; }
    }

    static readonly string m_TargetPath = Config.Asset.GetRepositoryPath + "/SpriteAtlas";
    static readonly string m_RootPath = Utility.Path.FormatStandardPath(Application.dataPath + "/");

    static readonly string m_PngEx = ".png";
    static readonly string m_SpineEx = ".asset";
    static readonly string m_FontEx = ".fontsettings";
    static readonly string m_SpriteAtlasEx = ".spriteatlas";
    static readonly string m_FileSearchPattern = "*.*";

    static int m_CreateAtlasCount = 0;
    static List<AtlasInfo> m_AtlasInfos = new List<AtlasInfo>();

    static SpriteAtlasPackingSettings packingSettings = new SpriteAtlasPackingSettings()
    {
        blockOffset = 1,
        enableRotation = false,
        enableTightPacking = false,
        padding = 4,
    };

    static SpriteAtlasTextureSettings textureSettings = new SpriteAtlasTextureSettings()
    {
        readable = false,
        generateMipMaps = false,
        sRGB = true,
        filterMode = FilterMode.Bilinear,
    };

    static TextureImporterPlatformSettings defaultPlatformSettings = new TextureImporterPlatformSettings()
    {
        name = "Default",
        format = TextureImporterFormat.Automatic,
    };

    static TextureImporterPlatformSettings standalonePlatformSettings = new TextureImporterPlatformSettings()
    {
        name = "Standalone",
        overridden = true,
        format = TextureImporterFormat.RGBA32,
    };

    static TextureImporterPlatformSettings iPhonePlatformSettings = new TextureImporterPlatformSettings()
    {
        name = "iPhone",
        overridden = true,
        format = TextureImporterFormat.ASTC_6x6,
    };

    static TextureImporterPlatformSettings androidPlatformSettings = new TextureImporterPlatformSettings()
    {
        name = "Android",
        overridden = true,
        format = TextureImporterFormat.ASTC_6x6,
    };

    [MenuItem("Assets/自定义创建/Sprite Atlas（选择文件夹）", false, -100)]
    private static void CreateSpriteAtlasByFloder()
    {
        CreateSpriteAtlas(true);
    }

    [MenuItem("Assets/自定义创建/Sprite Atlas", false, -99)]
    private static void CreateSpriteAtlasByFile()
    {
        CreateSpriteAtlas(false);
    }

    private static void CreateSpriteAtlas(bool isFolder)
    {
        m_CreateAtlasCount = 0;
        m_AtlasInfos.Clear();
        Object[] selects = Selection.GetFiltered(typeof(Object), SelectionMode.Assets);
        for (int i = 0; i < selects.Length; i++)
        {
            Object select = selects[i];
            string path = AssetDatabase.GetAssetPath(select);
            if (Directory.Exists(path))
            {
                if (isFolder)
                {
                    CreateAtlasByFloder(select);
                }
                else
                {
                    CreateAtlasByFiles(path);
                }

            }
        }
        CreateAtlasByInfo(isFolder);
        AssetDatabase.Refresh();
        Logger.Log("图集创建完成。共计{0}个资源".Format(m_CreateAtlasCount.ToString().RichTextGreenColor()));
        AssetDatabase.SaveAssets();
    }

    private static void CreateAtlasByFloder(Object obj)
    {
        string atlasName = GetAtlasName(obj.name);
        string atlasPath = Path.Combine(m_TargetPath, atlasName);
        AtlasInfo atlasInfo = new AtlasInfo()
        {
            AtlasName = atlasName,
            AtlasPath = atlasPath,
            Obj = obj,
        };
        m_AtlasInfos.Add(atlasInfo);
    }

    private static void CreateAtlasByFiles(string path)
    {
        DirectoryInfo directory = new DirectoryInfo(path);
        DirectoryInfo[] directories = directory.GetDirectories();
        for (int i = 0; i < directories.Length; i++)
        {
            CreateAtlasByFiles(path);
        }

        FileInfo[] files = directory.GetFiles(m_FileSearchPattern, SearchOption.TopDirectoryOnly);
        List<string> textures = new List<string>();
        for (int i = 0; i < files.Length; i++)
        {
            var file = files[i];
            if (file.Extension.Equals(m_PngEx))
            {
                string spinePath = file.FullName.Replace(m_PngEx, m_SpineEx);
                string fontPath = file.FullName.Replace(m_PngEx, m_FontEx);
                if (!File.Exists(spinePath) && !File.Exists(fontPath))
                {
                    textures.Add(file.FullName);
                }
            }
        }

        if (textures.Count > 0)
        {
            string atlasName = GetAtlasName(directory.Name);
            string atlasPath = Path.Combine(m_TargetPath, atlasName);
            AtlasInfo atlasInfo = new AtlasInfo()
            {
                AtlasName = atlasName,
                AtlasPath = atlasPath,
                TexturePaths = textures,
            };
            m_AtlasInfos.Add(atlasInfo);
        }
    }

    static string GetAtlasName(string floderName)
    {
        return floderName + m_SpriteAtlasEx;
    }

    static string GetAssetPath(string atlasPath)
    {
        string path = Utility.Path.FormatStandardPath(atlasPath);
        path = path.Replace(m_RootPath, "Assets/");
        return path;
    }

    static void CreateAtlasByInfo(bool isFolder)
    {
        AtlasInfo[] atlasInfos = m_AtlasInfos.ToArray();
        for (int i = 0; i < atlasInfos.Length; i++)
        {
            var atlasInfo = atlasInfos[i];
            string atlasPath = atlasInfo.AtlasPath;
            SpriteAtlas spriteAtlas;
            if (File.Exists(atlasPath))
            {
                File.Delete(atlasPath);
            }
            spriteAtlas = new SpriteAtlas();
            spriteAtlas.SetIncludeInBuild(true);
            spriteAtlas.SetPackingSettings(packingSettings);
            spriteAtlas.SetTextureSettings(textureSettings);
            spriteAtlas.SetPlatformSettings(defaultPlatformSettings);
            spriteAtlas.SetPlatformSettings(standalonePlatformSettings);
            spriteAtlas.SetPlatformSettings(iPhonePlatformSettings);
            spriteAtlas.SetPlatformSettings(androidPlatformSettings);

            if (isFolder)
            {
                spriteAtlas.Add(new Object[] { atlasInfo.Obj });
                AssetDatabase.CreateAsset(spriteAtlas, atlasPath);
            }
            else
            {
                List<Sprite> sprites = new List<Sprite>();
                string[] pathes = atlasInfo.TexturePaths.ToArray();
                for (int j = 0; j < pathes.Length; j++)
                {
                    string path = pathes[j];
                    Sprite sprite = AssetDatabase.LoadAssetAtPath<Sprite>(GetAssetPath(path));
                    if (sprite != null)
                    {
                        int width = sprite.texture.width;
                        int height = sprite.texture.height;
                        if (height > 1024 & width > 512)
                        {

                        }
                        else if (width > 1024 & height > 512)
                        {

                        }
                        else if (width <= 2048 & height <= 2048)
                        {
                            sprites.Add(sprite);
                        }
                    }
                }

                if (sprites.Count > 0)
                {
                    spriteAtlas.Add(sprites.ToArray());
                    AssetDatabase.CreateAsset(spriteAtlas, atlasPath);
                }
            }

            AssetDatabase.SaveAssets();
            m_CreateAtlasCount++;
        }
    }
}
